package org.nobject.common.lang;

import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import org.nobject.common.exception.ConvertException;

/**
 * Array工具类
 *
 * @author bianrongjun
 * @version 1.0
 */
public class ArrayUtils {
	
	/** 
	 * 比较两个数组，获取相同的交集、差异1、差异2
	 * EXP:
	 * 
	 * [1,2,3,4],[2,3,5]
	 * =>
	 * [2,3],[1,4],[5]
	 * 
	 * @param o1 数组1
	 * @param o2 数组2
	 * 
	 * @return [交集(o1,o2共有的)、差异1(o1独有的)、差异2(o2独有的)]
	 */
	public static List[] getCross(Object[] o1,Object[] o2){
		return getCross0(o1, o2);
	}

	/** 
	 * 比较两个数组，获取相同的交集、差异1、差异2
	 * 支持基础数据类型
	 * 
	 * @param o1 数组1
	 * @param o2 数组2
	 * 
	 * @return [交集(o1,o2共有的)、差异1(o1独有的)、差异2(o2独有的)]
	 */
	public static List[] getCross0(Object a1,Object a2){
		List mix=new LinkedList();
		
		if(a1==null) a1=new Object[]{};
		if(a2==null) a2=new Object[]{};
		
		List l1=ListUtils.toList0(a1);
		List l2=ListUtils.toList0(a2);
		for(int i=l1.size()-1;i>=0;i--){
			boolean has=false;
			Object oi=l1.get(i);
			for(int j=l2.size()-1;j>=0;j--){
				Object oj=l2.get(j);
				if(oj.equals(oi)){
					l2.remove(j);
					has=true;
				}
			}
			if(has){
				mix.add(0, oi);
				l1.remove(i);
			}
		}
		
		return new List[]{
			mix,l1,l2
		};
	}
	
	/** 
	 * 数组附加对象
	 * @param os 数组
	 * @param o 对象
	 */
	public static Object[] append(Object[] os,Object o){
		if(os==null) return o==null?null:new Object[]{o};
		if(o==null) return os;
		Object [] rs=new Object[os.length+1];
		System.arraycopy(os, 0, rs, 0, os.length);
		rs[os.length]=o;
		return rs;
	}
	
	/**
	 * 连接数组
	 * @param os 源数组
	 * @param as 附加组
	 */
	public static Object [] concat(Object [] os,Object [] as){
		if(as==null||as.length==0) return os;
		if(os==null) os=new Object[0];
		int al=os.length+as.length;
		Object[] rs=new Object[al];
		System.arraycopy(os, 0, rs, 0, os.length);
		System.arraycopy(as, 0, rs, os.length, as.length);
		return rs;
	}

	/**
	 * 连接数组
	 * @param os 源数组
	 * @param as 附加组
	 */
	public static Object [] concat(Object [] os,List as){
		return concat(os, toArray(as));
	}
	
	/** 
	 * 是否为空
	 * @param os 源数组
	 */
	public static boolean isEmpty(Object[] os){
		return os==null||os.length==0;
	}
	
	/** 
	 * isEmpty0
	 * @param os
	 */
	public static boolean isEmpty0(Object os){
		return os==null||Array.getLength(os)==0;
	}
	
	/** 
	 * hasEmpty
	 * @param os
	 * @return
	 */
	public static boolean hasEmpty(Object[] os){
		if(isEmpty(os)) return true;
		
		for(Object o:os){
			if(o==null) return true;
		}
		
		return false;
	}
	
//	/**
//	 * 前插
//	 * TODO 待优化用arraycopy
//	 * @param os 源数组
//	 * @param idx 插入点
//	 * @param is 插入组
//	 */
//	public static Object[] insertBefore(Object[]os ,int idx,List is){
//		if(is==null||is.size()==0) return os;
//		List l=new LinkedList();
//		if(os!=null){
//			for (int i = 0; i < os.length; i++)  l.add(os[i]);
//		}
//		l.addAll(idx, is);
//		return toArray(l,is.get(0).getClass());
//	}
	
	/**
	 * 截断数组
	 *
	 * @param os 源数组
	 * @param start 起始值
	 * @param count 数量
	 */
	public static Object subArray(Object[] os,int start,int count){
		if(os.length==0||os.length<start) return null;
		Class c=os[0].getClass();
		if(os.length<start+count){
			count=os.length-start;
		}
		Object nos=Array.newInstance(c, count);
		System.arraycopy(os, start, nos, 0, count);
		return nos;
	}
	
//	public static void main(String[] args) {
//		String [] s=new String[]{"1","2","3","4","5","6","7"};
//		String [] ss=(String[])subArray(s, 7, 2);
//		System.out.println(ss);
//		if(ss==null) return;
//		System.out.println(StringUtils.toString(ss) );
//	}
	
	/** 
	 * 转化为Array
	 * @param collection 集合
	 * @param clazz 类型
	 */
	public static Object[] toArray(Collection collection,Class clazz){
		return (Object[])toArray0(collection, clazz);
	}
	
//	public static void main(String[] args) {
//		List l=new LinkedList();
//		l.add(new String[]{"1","2"});
//		l.add(new String[]{"1","2"});
//		
//		String[][] s=(String[][])toArray(l, String[].class);
//		System.out.println(s[0][0]);
//		
////	
////		List l=new LinkedList();
////		l.add(1l);
////		long[] a=(long[]) toArray0(l,long.class);
////		System.out.println(a[0]);
//	}
	/** 
	 * 转化为Array
	 * 
	 * 支持基本类型如int.class
	 * 
	 * 如果是多维数据 List转String[][],clazz必须是最外围的类型才行：
	 * 
	 * Exp:
	 * List l=new LinkedList();
	 * l.add(new String[]{"1","2"});
	 * l.add(new String[]{"1","2"});
	 * String[][] result=(String[][])toArray0(l,String[].class);
	 * 
	 * @param collection 集合
	 * @param clazz 目标类型
	 */
	public static Object toArray0(Collection collection,Class clazz){
		if(collection==null) return null;
		Object a=Array.newInstance(clazz, collection.size());
		int i=0;
		for(Iterator iter=collection.iterator();iter.hasNext();){
			Array.set(a,i,iter.next());
			i++;
		}
		return a;
	}
	
	
	/** 
	 * 转化为Array
	 * @param collection 集合
	 */
	public static Object [] toArray(Collection collection){
		return toArray(collection, Object.class);
	}
	
	/**
	 * 转化为字符串
	 * @param ss 字符串数组
	 * @param spliter 分隔符
	 */
	public static String join(String[] ss,String spliter){
		if(ss==null||ss.length==0) return null;
		if(StringUtils.isEmpty(spliter)) spliter="";
		StringBuffer sb=new StringBuffer();
		for (int i = 0; i < ss.length; i++) {
			if(i!=0) sb.append(spliter);
			sb.append(StringUtils.null2Empty(ss[i]));
		}
		return sb.toString();
	}
	
	/**
	 * 转化为字符串
	 * @param ss 字符串数组
	 * @param spliter 分隔符
	 */
	public static String join0(Object ss,String spliter){
		if(ss==null) return null;
		int l=Array.getLength(ss);
		if(l==0) return null;
		if(StringUtils.isEmpty(spliter)) spliter="";
		StringBuffer sb=new StringBuffer();
		for (int i = 0; i < l; i++) {
			if(i!=0) sb.append(spliter);
			sb.append(StringUtils.toString0(Array.get(ss, i)));
		}
		return sb.toString();
	}
	
	/** 
	 * 获取索引
	 * @param os 源数组
	 * @param o 目标对象
	 */
	public static int getIdx(Object[] os,Object o){
		for (int i = 0; i < os.length; i++) {
			if(os[i].equals(o)) return i;
		}
		return -1;
	}
	
	/** 
	 * 比对两个乱序的数组
	 * @param os1 数组1
	 * @param os2 数组2
	 */
	public static boolean equals(Object[] os1,Object[] os2){
		if(os1==null&&os2==null) return true;
		else if(os1==null||os2==null) return false;
		
		if(os1.length!=os2.length) return false;
		
		try {
			Collection os2s=CollectionUtils.toCollection(os2);
			for(Object o:os1){
				if(os2s.contains(o)){
					os2s.remove(o);
				}else{
					return false;
				}
			}
			return os2s.size()==0;
		} catch (ConvertException e) {
			throw new RuntimeException(e);
		}
	}
	
	public static void main(String[] args) {
		System.out.println(equals(
			new Object[]{"1","3",true},
			new Object[]{"1",true,"3"}
		));
		
	}
}
